(in-package :procemu)

(defclass jump-instruction (instruction)
  ((destination	:accessor destination
		:documentation "The jump destination as a location"))
  (:documentation "Jump to some destination, possibly conditionally"))

;; Subclasses can define :around methods
(defmethod perform ((instruction jump-instruction) (cpu cpu))
  (setf (instruction-pointer cpu)
	(location cpu (destination instruction))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defclass jmp (jump-instruction)
  ()
  (:documentation "Jump unconditionally to a destination"))

(defmethod print-object ((instruction jmp) stream)
  (print-unreadable-object (instruction stream :type t)
    (format stream "~S" (destination instruction))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defclass je (jump-instruction)
  ((location-1 :initarg :location-1)
   (location-2 :initarg :location-2))
  (:documentation "Jump if two locations are equal"))

(defmethod perform :around ((instruction je) (cpu cpu))
  (with-slots (location-1 location-2) instruction
    (when (= (location cpu location-1)
	     (location cpu location-2))
      (call-next-method))))